﻿using System;
using System.Text;

namespace MyFastDataSourceBind
{
    /// <summary>
    /// 数据源对象
    /// </summary>
    /// <remarks>编写 袁永福</remarks>
    public class XDataSource
    {
        #region 开发人员可以根据需要修改这里的代码

        /// <summary>
        /// 静态构造函数,添加应用系统所需的数据源对象
        /// </summary>
        static XDataSource()
        {
            try
            {
                myInstances = new System.Collections.ArrayList();
                // 为数据表 Customers 创建全局数据源对象
                myInstances.Add(CreateInstance("Customers"));
                // 为数据表 Employees 创建全局数据源对象
                myInstances.Add(CreateInstance("Employees"));
                // 为数据表 Orders 创建全局数据源对象
                myInstances.Add(CreateInstance("Orders"));
                // 为数据表 Products 创建全局数据源对象
                myInstances.Add(CreateInstance("Products"));
                // 为数据表 Region 创建全局数据源对象
                myInstances.Add(CreateInstance("Region"));
                // 为数据表 Suppliers 创建全局数据源对象
                myInstances.Add(CreateInstance("Suppliers"));
            }
            catch (Exception ext)
            {
                System.Windows.Forms.MessageBox.Show(ext.ToString());
            }
        }

        /// <summary>
        /// 生成新的字段值
        /// </summary>
        /// <param name="Sender">事件发起者</param>
        /// <param name="Args">事件参数</param>
        private static void GenerateNewFieldValue(object Sender, GenerateNewFieldValueEventArgs Args)
        {
            // 获得数据源名，一般是数据表的名称
            string dsName = Args.DataSourceName.Trim().ToUpper();
            // 获得字段名
            string fieldName = Args.DataFieldName.Trim().ToUpper();
            if (dsName == "CUSTOMERS")
            {
                if (fieldName == "CUSTOMERID")
                {
                    // 对于Customers表的CustomerID字段生成随机的客户编号
                    Random rnd = new Random();
                    char[] values = new char[5];
                    for (int iCount = 0; iCount < values.Length; iCount++)
                    {
                        values[iCount] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rnd.Next(0, 25)];
                    }
                    Args.NewValue = new string(values);
                }
                else if (fieldName == "COMPANYNAME")
                {
                    // 设置Customers表的CompanyName字段初始化值
                    Args.NewValue = "新建客户";
                }
            }
            else if (dsName == "EMPLOYEES" && fieldName == "EMPLOYEEID")
            {
                // 对于Employees表的EmployeeID字段查询生成新的员工编号
                Args.NewValue = ConnectionHelper.GenerateID(dsName, fieldName);
            }
            else if (dsName == "ORDERS" && fieldName == "ORDERID")
            {
                // 对于Orders表的OrderID字段查询生成新的订单编号
                Args.NewValue = ConnectionHelper.GenerateID(dsName, fieldName);
            }
            else if (dsName == "PRODUCTS" && fieldName == "PRODUCTID")
            {
                // 对于Products表的ProductID字段查询生成新的货物编号
                Args.NewValue = ConnectionHelper.GenerateID(dsName, fieldName);
            }
            else if (dsName == "REGION" && fieldName == "REGIONID")
            {
                // 对于Region表的RegionID字段查询生成新的地区编号
                Args.NewValue = ConnectionHelper.GenerateID(dsName, fieldName);
            }
            else if (dsName == "SUPPLIERS" && fieldName == "SUPPLIERID")
            {
                // 对于Suppliers表的SupplierID字段查询生成新的供货商编号
                Args.NewValue = ConnectionHelper.GenerateID(dsName, fieldName);
            }
        }

        #endregion

        #region 数据源全局列表 ********************************************************

        private static System.Collections.ArrayList myInstances = new System.Collections.ArrayList();
        /// <summary>
        /// 添加对象实例
        /// </summary>
        /// <param name="ds">要添加的对象实例</param>
        public static void AddInstance(XDataSource ds)
        {
            myInstances.Add(ds);
        }

        /// <summary>
        /// 获得对象实例
        /// </summary>
        /// <param name="name">数据源名称</param>
        /// <returns>获得的数据源对象</returns>
        public static XDataSource GetInstance(string name)
        {
            foreach (XDataSource ds in myInstances)
            {
                if (string.Compare(ds.Name, name, true) == 0)
                {
                    return ds;
                }
            }
            return null;
        }
        /// <summary>
        /// 获得所有的数据源对象数组
        /// </summary>
        /// <returns>数据源对象数组</returns>
        public static XDataSource[] GetInstances()
        {
            return (XDataSource[])myInstances.ToArray(typeof(XDataSource));
        }

        #endregion

        /// <summary>
        /// 根据数据表名创建新的对象实例
        /// </summary>
        /// <param name="TableName">数据表名</param>
        /// <returns>创建的数据源对象</returns>
        public static XDataSource CreateInstance(string TableName)
        {
            // 获得指定名称的数据库表的结构信息
            XDesignerData.TableInfo tableInfo = ConnectionHelper.DBInfo.Tables[TableName];
            if (tableInfo == null || tableInfo.Fields.Count == 0)
                return null;
            // 新建一个数据源对象
            XDataSource ds = new XDataSource();
            ds.Name = tableInfo.Name;
            ds.TableName = tableInfo.Name;
            ds.Description = tableInfo.Remark;
            // 保存所有关键字段名的列表
            System.Collections.ArrayList KeyFields = new System.Collections.ArrayList();
            // 保存所有字段名的数组
            string[] FieldNames = new string[tableInfo.Fields.Count];
            for (int iCount = 0; iCount < tableInfo.Fields.Count; iCount++)
            {
                FieldNames[iCount] = tableInfo.Fields[iCount].Name;
                if (tableInfo.Fields[iCount].PrimaryKey)
                {
                    KeyFields.Add(tableInfo.Fields[iCount].Name);
                }
            }
            // 获得所有的关键字段名
            string[] KeyFieldNames = null;
            if (KeyFields.Count > 0)
            {
                KeyFieldNames = (string[])KeyFields.ToArray(typeof(string));
            }

            ds.KeyFieldNames = KeyFieldNames;

            // 初始化查询数据命令对象
            ds.SelectCommand = new XDBCommandInfo();
            ds.SelectCommand.CommandText = SQLTextBuilder.BuildSelect(
                tableInfo.Name,
                FieldNames,
                null,
                true);

            // 初始化插入数据命令对象
            ds.InsertCommand = new XDBCommandInfo();
            ds.InsertCommand.CommandText = SQLTextBuilder.BuildInsert(
                tableInfo.Name,
                FieldNames,
                true);
            foreach (string name in FieldNames)
            {
                XDBParameterInfo p = new XDBParameterInfo();
                p.Name = name;
                p.SourceColumn = name;
                ds.InsertCommand.Parameters.Add(p);
            }

            if (KeyFieldNames != null)
            {
                // 初始化更新数据命令对象
                ds.UpdateCommand = new XDBCommandInfo();
                ds.UpdateCommand.CommandText = SQLTextBuilder.BuildUpdate(
                    tableInfo.Name,
                    FieldNames,
                    KeyFieldNames,
                    true);
                foreach (string name in FieldNames)
                {
                    XDBParameterInfo p = new XDBParameterInfo();
                    p.Name = name;
                    p.SourceColumn = name;
                    ds.UpdateCommand.Parameters.Add(p);
                }
                foreach (string name in KeyFieldNames)
                {
                    XDBParameterInfo p = new XDBParameterInfo();
                    p.Name = SQLTextBuilder.ConditionParameterPrefix + name;
                    p.SourceColumn = name;
                    ds.UpdateCommand.Parameters.Add(p);
                }
                // 初始化删除数据命令对象
                ds.DeleteCommand = new XDBCommandInfo();
                ds.DeleteCommand.CommandText = SQLTextBuilder.BuildDelete(
                    tableInfo.Name, KeyFieldNames, true);
                foreach (string name in KeyFieldNames)
                {
                    XDBParameterInfo p = new XDBParameterInfo();
                    p.Name = SQLTextBuilder.ConditionParameterPrefix + name;
                    p.SourceColumn = name;
                    ds.DeleteCommand.Parameters.Add(p);
                }
            }
            return ds;
        }



        /// <summary>
        /// 初始化对象
        /// </summary>
        public XDataSource()
        {
        }

        private string strName = null;
        /// <summary>
        /// 数据源名称
        /// </summary>
        public string Name
        {
            get { return strName; }
            set { strName = value; }
        }

        private string strTableName = null;
        /// <summary>
        /// 数据源操作的数据表的名称，一般的TableName等于Name属性
        /// </summary>
        public string TableName
        {
            get { return strTableName; }
            set { strTableName = value; }
        }

        private string strDescription = null;
        /// <summary>
        /// 数据源说明
        /// </summary>
        public string Description
        {
            get { return strDescription; }
            set { strDescription = value; }
        }



        private XDBCommandInfo myInsertCommand = null;
        /// <summary>
        /// 插入数据用的命令信息对象
        /// </summary>
        public XDBCommandInfo InsertCommand
        {
            get { return myInsertCommand; }
            set { myInsertCommand = value; }
        }

        private XDBCommandInfo myUpdateCommand = null;
        /// <summary>
        /// 更新数据用的命令信息对象
        /// </summary>
        public XDBCommandInfo UpdateCommand
        {
            get { return myUpdateCommand; }
            set { myUpdateCommand = value; }
        }

        private XDBCommandInfo myDeleteCommand = null;
        /// <summary>
        /// 删除数据用的命令信息对象
        /// </summary>
        public XDBCommandInfo DeleteCommand
        {
            get { return myDeleteCommand; }
            set { myDeleteCommand = value; }
        }

        private bool bolEditing = false;
        /// <summary>
        /// 数据源正处于编辑状态
        /// </summary>
        public bool Editing
        {
            get
            {
                return bolEditing;
            }
        }

        /// <summary>
        /// 当前行数据是否改变标记
        /// </summary>
        public bool CurrnetRowModified
        {
            get
            {
                if (myCurrentRow != null)
                {
                    return myCurrentRow.RowState != System.Data.DataRowState.Unchanged;
                }
                return false;
            }
        }

        private string[] myKeyFieldNames = null;
        /// <summary>
        /// 关键字段名列表
        /// </summary>
        public string[] KeyFieldNames
        {
            get { return myKeyFieldNames; }
            set { myKeyFieldNames = value; }
        }

        /// <summary>
        /// 判断指定的字段数据能否编辑数值
        /// </summary>
        /// <param name="FieldName">字段名</param>
        /// <returns>能否编辑数值</returns>
        public bool CanEdit(string FieldName)
        {
            if (bolEditing == false)
                return false;
            if (myCurrentRow.RowState == System.Data.DataRowState.Added)
            {
                // 若当前记录是新增的记录，则所有字段都可编辑
                return true;
            }
            // 关键字段是不能编辑的
            return IsKeyField(FieldName) == false;
        }

        /// <summary>
        /// 判断指定名称的字段是否为关键字段
        /// </summary>
        /// <param name="FieldName">字段名</param>
        /// <returns>是否为关键字段</returns>
        public bool IsKeyField(string FieldName)
        {
            if (FieldName == null || FieldName.Trim().Length == 0)
            {
                throw new ArgumentNullException("FieldName");
            }
            FieldName = FieldName.Trim();
            if (myKeyFieldNames != null && myKeyFieldNames.Length > 0)
            {
                foreach (string name in myKeyFieldNames)
                {
                    if (string.Compare(name, FieldName, true) == 0)
                    {
                        return true;
                    }
                }
            }
            return false;
        }



        #region 加载数据

        /// <summary>
        /// 内部保存数据的DataTable
        /// </summary>
        private System.Data.DataTable myDataTable = null;
        /// <summary>
        /// 内置的保存数据的数据表对象
        /// </summary>
        public System.Data.DataTable DataTable
        {
            get { return myDataTable; }
        }

        private int intDataTableVersion = 0;
        /// <summary>
        /// 返回内置数据的版本号
        /// </summary>
        public int DataTableVersion
        {
            get { return intDataTableVersion; }
        }

        /// <summary>
        /// 至少有一条数据库记录
        /// </summary>
        private bool bolAtLeastOneRecord = false;
        /// <summary>
        /// 至少有一条数据库记录
        /// </summary>
        /// <remarks>
        /// 查询数据库填充数据源时，若数据库中没有任何数据，则数据源没有任何记录，
        /// 但若设置该属性值时，系统会自动创建一个新的记录并添加到数据源中。使得
        /// 数据源对象保证至少有一条记录。
        /// </remarks>
        public bool AtLeastOneRecord
        {
            get { return bolAtLeastOneRecord; }
            set { bolAtLeastOneRecord = value; }
        }

        private XDBCommandInfo mySelectCommand = null;
        /// <summary>
        /// 查询数据用的命令信息对象
        /// </summary>
        public XDBCommandInfo SelectCommand
        {
            get { return mySelectCommand; }
            set { mySelectCommand = value; }
        }
        /// <summary>
        /// 清空内部缓存的数据
        /// </summary>
        public void ClearDataTable()
        {
            bolEditing = false;
            myCurrentRow = null;
            if (myDataTable != null)
            {
                myDataTable.Dispose();
                myDataTable = null;
            }
            intDataTableVersion++;
        }
        /// <summary>
        /// 刷新数据源的状态
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool Refresh()
        {
            ClearDataTable();
            return CheckDataTable();
        }

        /// <summary>
        /// 检查缓存的数据状态
        /// </summary>
        /// <returns>数据能否使用</returns>
        public bool CheckDataTable()
        {
            if (myDataTable != null)
            {
                // 若数据表不为数据可用
                return true;
            }
            if (mySelectCommand == null)
            {
                // 若SelectCommand值为空则对象状态不对，抛出异常
                throw new InvalidOperationException("SelectCommand is null");
            }
            // 开始加载数据
            intDataTableVersion++;
            // 根据SelectCommand值调用数据库操作底层查询数据获得数据表
            myDataTable = ConnectionHelper.ReadDataTable(mySelectCommand);
            if (myDataTable.Rows.Count == 0 && bolAtLeastOneRecord)
            {
                // 执行至少有一条记录的操作
                myCurrentRow = this.NewDataRow();
                myDataTable.Rows.Add(myCurrentRow);
                // 向用户界面层广播数据源的数据发生改变
                XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.FillUI);
            }
            else if (myDataTable.Rows.Count > 0)
            {
                // 设置当前数据行
                myCurrentRow = myDataTable.Rows[0];
                // 向用户界面层广播数据源的数据发生改变
                XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.FillUI);
            }
            return true;
        }

        #endregion



        #region 当前记录导航

        /// <summary>
        /// 当前数据源的记录的总行数
        /// </summary>
        public int RowCount
        {
            get
            {
                if (myDataTable == null)
                    return 0;
                else
                    return myDataTable.Rows.Count;
            }
        }
        /// <summary>
        /// 数据源是否有数据
        /// </summary>
        public bool HasRecord
        {
            get
            {
                return myDataTable != null && myDataTable.Rows.Count > 0;
            }
        }

        /// <summary>
        /// 当前处理的数据行对象
        /// </summary>
        private System.Data.DataRow myCurrentRow = null;

        /// <summary>
        /// 从0开始计算的当前处理的数据行行号
        /// </summary>
        public int RowIndex
        {
            get
            {
                if (myDataTable != null && myCurrentRow != null)
                {
                    // 若当前数据源行有效则返回当前行在数据表中的序号
                    return myDataTable.Rows.IndexOf(myCurrentRow);
                }
                else
                {
                    return -1;
                }
            }
            set
            {
                // 设置当前数据源行
                SetRowIndex(value, true);
            }
        }
        /// <summary>
        /// 设置当前处理的数据行
        /// </summary>
        /// <param name="NewIndex">新的行号</param>
        /// <param name="RaiseEvent">是否触发事件</param>
        private void SetRowIndex(int NewIndex, bool RaiseEvent)
        {
            if (myDataTable != null && myDataTable.Rows.Count > 0)
            {
                // 修正新的行号
                if (NewIndex < 0)
                    NewIndex = 0;
                if (NewIndex >= myDataTable.Rows.Count)
                    NewIndex = myDataTable.Rows.Count - 1;
                if (NewIndex >= 0 && NewIndex < myDataTable.Rows.Count)
                {
                    // 根据新的当前行号设置当前处理的数据行对象
                    myCurrentRow = myDataTable.Rows[NewIndex];
                    if (RaiseEvent)
                    {
                        // 若需要触发事件则调用数据源事件广播器向用户界面层广播事件
                        XDataSourceEventSender.RaiseEvent(
                            this,
                            XDataSourceEventStyle.FillUI);
                    }
                }
            }
        }

        /// <summary>
        /// 判断能否执行移动到第一条记录的操作
        /// </summary>
        public bool CanMoveFirst
        {
            get
            {
                if (bolEditing)
                {
                    // 若数据源处于编辑状态则不能移动当前数据行
                    return false;
                }
                if (myDataTable != null && myDataTable.Rows.Count > 0)
                {
                    // 只用当前数据行号大于0才能执行操作。
                    // 若当前数据行为0，也就是第一行则不能执行本操作。
                    return this.RowIndex > 0;
                }
                return false;
            }
        }
        /// <summary>
        /// 移动到第一条记录
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool MoveFirst()
        {
            if (CanMoveFirst)
            {
                // 若能执行本操作则设置当前行号为0
                this.RowIndex = 0;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断能否执行移动到前一条记录的操作
        /// </summary>
        public bool CanMovePrevious
        {
            get
            {
                if (bolEditing)
                {
                    // 若数据源处于编辑状态则不能移动当前数据行
                    return false;
                }
                if (myDataTable != null && myDataTable.Rows.Count > 0)
                {
                    if (this.RowIndex > 0)
                    {
                        // 若当前行号大于0则可以执行操作。
                        // 若当前行号等于0，也就是第一行为当前行，则该记录没有
                        // 前一条记录，无法执行操作。
                        return true;
                    }
                }
                return false;
            }
        }
        /// <summary>
        /// 移动到前一条记录
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool MovePrevious()
        {
            if (this.CanMovePrevious)
            {
                // 若能执行本操作则设置当前行号减1。
                this.RowIndex = this.RowIndex - 1;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断能否执行移动到下一条记录的操作
        /// </summary>
        public bool CanMoveNext
        {
            get
            {
                if (bolEditing)
                {
                    // 若数据源处于编辑状态则不能移动当前数据行
                    return false;
                }
                if (myDataTable != null && myDataTable.Rows.Count > 0)
                {
                    if (this.RowIndex < myDataTable.Rows.Count - 1)
                    {
                        // 若当前记录不是最后一条记录则操作有效，
                        // 否则操作无效。
                        return true;
                    }
                }
                return false;
            }
        }

        /// <summary>
        /// 移动到下一条记录
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool MoveNext()
        {
            if (CanMoveNext)
            {
                // 若操作有效则设置当前行号加1。
                this.RowIndex = this.RowIndex + 1;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断能否执行移动到最后一条记录的操作
        /// </summary>
        public bool CanMoveLast
        {
            get
            {
                if (bolEditing)
                {
                    // 若数据源处于编辑状态则不能移动当前数据行
                    return false;
                }
                if (myDataTable != null && myDataTable.Rows.Count > 0)
                {
                    if (this.RowIndex != myDataTable.Rows.Count - 1)
                    {
                        // 若当前记录不是最后一条记录则操作有效，
                        // 否则操作无效。
                        return true;
                    }
                }
                return false;
            }
        }

        /// <summary>
        /// 移动到最后一条记录
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool MoveLast()
        {
            if (CanMoveLast)
            {
                // 若操作有效则设置当前行号为最后一条记录的行号。
                this.RowIndex = myDataTable.Rows.Count - 1;
                return true;
            }
            return false;
        }
        ///// <summary>
        ///// 移动到指定位置的记录
        ///// </summary>
        ///// <param name="index">记录序号</param>
        ///// <returns>操作是否成功</returns>
        //public bool MoveTo(int index)
        //{
        //    if (bolEditing)
        //        return false;
        //    if (myDataTable != null && myDataTable.Rows.Count > 0)
        //    {
        //        if (index >= 0 && index < myDataTable.Rows.Count)
        //        {
        //            this.RowIndex = index;
        //            return true;
        //        }
        //    }
        //    return false;
        //}

        #endregion

        /// <summary>
        /// 删除当前行数据
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool DeleteRecord()
        {
            if (myCurrentRow != null)
            {
                // 广播数据源当前记录即将删除事件，其他模块可以响应事件来阻止删除操作
                if (XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.BeforeDelete))
                {
                    // 退出编辑状态
                    bolEditing = false;
                    // 获得当前行号
                    int index = this.RowIndex;
                    // 是否需要更新数据库
                    bool update = (myCurrentRow.RowState != System.Data.DataRowState.Added);
                    // 删除当前数据行
                    myCurrentRow.Delete();
                    // 更新数据版本
                    intDataTableVersion++;
                    if (update)
                    {
                        // 调用数据库处理层更新缓存的数据到数据库中
                        // 由于当前数据行的状态为删除的则会删除数据库中的数据
                        ConnectionHelper.UpdateDataSource(this);
                    }
                    // 重新设置当前数据行
                    this.SetRowIndex(index, false);
                    // 广播数据源事件，通知用户界面层更新用户界面。
                    XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.FillUI);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 新增记录操作
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool NewRecord()
        {
            if (myDataTable != null)
            {
                // 广播数据源准备新增记录事件
                // 用户界面层可以响应这个事件，若程序觉得当前状态
                // 不适合新增记录则可以撤销新增记录操作。
                if (XDataSourceEventSender.RaiseEvent(
                    this,
                    XDataSourceEventStyle.BeforeNewRecord))
                {
                    // 根据数据表的结构创建新的数据行对象
                    System.Data.DataRow row = NewDataRow();
                    if (row == null)
                        return false;
                    // 将新的数据行对象添加到数据表中
                    myDataTable.Rows.Add(row);
                    // 设置新的数据行为当前数据行
                    myCurrentRow = row;
                    // 根据内部版本号
                    intDataTableVersion++;
                    // 设置数据源编辑标记，通知用户界面层进入编辑状态
                    bolEditing = true;
                    // 广播数据源更新用户界面事件
                    XDataSourceEventSender.RaiseEvent(
                        this,
                        XDataSourceEventStyle.FillUI);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 创建新的数据行对象
        /// </summary>
        /// <returns>新的数据行对象</returns>
        protected virtual System.Data.DataRow NewDataRow()
        {
            if (myDataTable != null)
            {
                // 根据数据表结构创建新的数据行对象
                System.Data.DataRow row = myDataTable.NewRow();
                foreach (System.Data.DataColumn col in myDataTable.Columns)
                {
                    // 遍历所有的数据表栏目，为新的数据行的每个栏目初始化值。
                    GenerateNewFieldValueEventArgs args = new GenerateNewFieldValueEventArgs(
                        this,
                        col.ColumnName,
                        col.DefaultValue,
                        col.DataType);
                    GenerateNewFieldValue(this, args);
                    if (args.Cancel)
                    {
                        // 若取消操作则返回空值
                        return null;
                    }
                    // 初始化字段值
                    row[col] = args.NewValue;
                }
                return row;
            }
            return null;
        }

        /// <summary>
        /// 进入数据编辑状态
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool BeginEdit()
        {
            if (myDataTable != null)
            {
                if (bolEditing)
                {
                    // 若已经处于编辑模式则退出
                    return false;
                }
                // 广播数据源开始编辑当前记录事件，若主程序觉得不能
                // 编辑数据源的数据可以响应该事件并取消操作。
                if (XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.BeforeEdit))
                {
                    // 设置数据源编辑状态
                    bolEditing = true;
                    // 向用户界面层广播数据源事件，用户界面可以进入编辑状态
                    XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.FillUI);
                    return true;
                }
            }
            return false;
        }



        /// <summary>
        /// 取消编辑
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool CancelEdit()
        {
            if (myDataTable != null)
            {
                if (bolEditing == false)
                {
                    // 若没处于编辑状态则退出
                    return false;
                }
                // 取消编辑状态
                bolEditing = false;
                // 获得当前数据行号
                int index = this.RowIndex;
                // 调用数据表的RejectChanges方法取消对数据表的任何修改
                myDataTable.RejectChanges();
                // 更新数据表版本号
                intDataTableVersion++;
                // 重新设置当前数据行号，由于数据源之前进入编辑状态是因为新增记录，而取消操作后
                // 新增的记录被删除了，于是当前行不存在了，在这里需要重新设置当前行号。
                this.SetRowIndex(index, false);
                // 向用户界面层广播数据源事件，通知更新用户界面
                XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.FillUI);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <returns></returns>
        public bool SaveRecord()
        {
            if (myDataTable != null)
            {
                if (bolEditing)
                {
                    // 若正处于编辑状态则继续

                    // 广播数据源事件，通知用户界面层向数据源回填数据，由于某些原因，例如
                    // 用户输入的数据不合法，则用户界面层可以取消更新数据的操作。
                    if (XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.ReadUI))
                    {
                        // 数据源退出编辑状态
                        bolEditing = false;
                        // 获得当前行号
                        int index = this.RowIndex;
                        // 调用数据库处理层更新数据源中缓存的数据到数据库中。
                        ConnectionHelper.UpdateDataSource(this);
                        // 更新数据表版本
                        intDataTableVersion++;
                        // 重新设置当前行号
                        this.SetRowIndex(index, false);
                        // 广播数据源事件，通知用户界面层更新界面
                        XDataSourceEventSender.RaiseEvent(this, XDataSourceEventStyle.FillUI);
                        return true;
                    }
                }
            }
            return false;
        }


        #region 向用户界面层提供数据

        /// <summary>
        /// 判断指定名称的字段的序号
        /// </summary>
        /// <param name="FieldName">字段名</param>
        /// <returns>序号</returns>
        private int IndexOfColumn(string FieldName)
        {
            if (myDataTable != null)
            {
                for (int iCount = 0; iCount < myDataTable.Columns.Count; iCount++)
                {
                    // 遍历数据表的所有的字段，进行字段名的匹配
                    if (ConnectionHelper.CompareFieldName(
                        FieldName,
                        myDataTable.Columns[iCount].ColumnName))
                    {
                        return iCount;
                    }
                }
            }
            return -1;
        }

        /// <summary>
        /// 获得当前行的指定字段的数据
        /// </summary>
        /// <param name="FieldName">字段名称</param>
        /// <returns>获得的数据</returns>
        public object GetValue(string FieldName)
        {
            // 找到指定名称的字段的序号
            int index = IndexOfColumn(FieldName);
            if (index >= 0 && myCurrentRow != null)
            {
                // 返回当前数据行的指定序号的数值
                return myCurrentRow[index];
            }
            return DBNull.Value;
        }


        /// <summary>
        /// 获得指定字段的所有的数据
        /// </summary>
        /// <param name="FieldName">字段名</param>
        /// <returns>数据组成的数组</returns>
        public object[] GetValues(string FieldName)
        {
            // 找到指定名称的字段的序号
            int index = IndexOfColumn(FieldName);
            if (index >= 0)
            {
                System.Collections.ArrayList list = new System.Collections.ArrayList();
                foreach (System.Data.DataRow row in myDataTable.Rows)
                {
                    // 遍历所有的数据行，获得指定序号的字段的值
                    list.Add(row[index]);
                }
                return list.ToArray();
            }
            return null;
        }



        #endregion

        #region 修改数据源的数据

        /// <summary>
        /// 设置当前行的指定字段的数据
        /// </summary>
        /// <param name="FieldName">字段名</param>
        /// <param name="Value">新数据</param>
        public void SetValue(string FieldName, object Value)
        {
            // 根据字段名获得字段序号
            int index = IndexOfColumn(FieldName);
            if (index >= 0 && myCurrentRow != null)
            {
                // 获得存储数据时的数据类型
                Type DataType = myDataTable.Columns[index].DataType;
                if (DataType == null)
                {
                    // 若没有指定存储的数据类型则直接设置数据
                    myCurrentRow[index] = Value;
                }
                else
                {
                    // 若指定的存储的数据类型则需要进行类型转换处理
                    myCurrentRow[index] = ConvertValueType(Value, DataType);
                }
                intDataTableVersion++;
            }
        }
        /// <summary>
        /// 进行数据类型转换
        /// </summary>
        /// <param name="v">原始数据</param>
        /// <param name="ValueType">要转换为的数据类型</param>
        /// <returns>转换后的数据</returns>
        private object ConvertValueType(object v, Type ValueType)
        {
            if (ValueType == null)
            {
                return v;
            }
            if (v == null || DBNull.Value.Equals(v))
            {
                // 若原始数据为空则返回数据库空值
                return DBNull.Value;
            }
            if (v.GetType().Equals(ValueType))
            {
                // 若原始数据的数据类型和存储类型一致则无需转换
                return v;
            }
            if (v is string)
            {
                // 若原始数据为字符串则需要进行长度判断
                // 若字符串为空则返回数据库空值
                // 在一些数据库操作中，若要插入或更新空的字符串值则会报错
                // 在此进行一些判断操作。
                string txt = (string)v;
                if (ValueType.Equals(typeof(string)))
                {
                    if (txt.Length > 0)
                        return txt;
                }
                if (txt.Trim().Length == 0)
                {
                    return DBNull.Value;
                }
            }
            try
            {
                if (ValueType.Equals(typeof(string)))
                {
                    // 若存储类型为字符串则将原始数值转换为字符串
                    return Convert.ToString(v);
                }
                if (ValueType.Equals(typeof(bool)))
                {
                    // 若存储类型为布尔类型则将原始数值转换为布尔值
                    if (v is String)
                    {
                        string Text = (string)v;
                        Text = Text.Trim();
                        if (Text == "1" || Text == "-1")
                            return true;
                        if (Text == "0")
                            return false;
                        if (string.Compare(Text, "true", true) == 0)
                            return true;
                        if (string.Compare(Text, "false", true) == 0)
                            return false;
                        return DBNull.Value;
                    }
                    return Convert.ToBoolean(v);
                }

                // 根据不同的数据存储类型进行相应的数据类型的转换
                if (ValueType.Equals(typeof(char)))
                    return Convert.ToChar(v);
                if (ValueType.Equals(typeof(byte)))
                    return Convert.ToByte(v);
                if (ValueType.Equals(typeof(sbyte)))
                    return Convert.ToSByte(v);
                if (ValueType.Equals(typeof(short)))
                    return Convert.ToInt16(v);
                if (ValueType.Equals(typeof(ushort)))
                    return Convert.ToUInt16(v);
                if (ValueType.Equals(typeof(int)))
                    return Convert.ToInt32(v);
                if (ValueType.Equals(typeof(uint)))
                    return Convert.ToUInt32(v);
                if (ValueType.Equals(typeof(long)))
                    return Convert.ToInt64(v);
                if (ValueType.Equals(typeof(ulong)))
                    return Convert.ToUInt64(v);
                if (ValueType.Equals(typeof(float)))
                    return Convert.ToSingle(v);
                if (ValueType.Equals(typeof(double)))
                    return Convert.ToDouble(v);
                if (ValueType.Equals(typeof(decimal)))
                {
                    decimal dec = Convert.ToDecimal(Convert.ToSingle(v));// .ToDecimal( v );
                    return dec;

                }
                if (ValueType.Equals(typeof(DateTime)))
                {
                    // 若存储类型为时间类型则将原始数据转换为时间类型
                    DateTime dtm = Convert.ToDateTime(v);
                    return dtm;
                }
                if (ValueType.Equals(typeof(byte[])))
                {
                    // 若存储类型为字节数组则将原始数据转换为字节数组
                    // 若原始数据为字符串则视其为Base64格式的字符串
                    // 将其转换为字节数组
                    if (v is byte[])
                        return v;
                    if (v is string)
                    {
                        return Convert.FromBase64String((string)v);
                    }
                    return DBNull.Value;
                }
            }
            catch (Exception ext)
            {
#if DEBUG
                System.Windows.Forms.MessageBox.Show(ext.ToString());
#endif
                return DBNull.Value;
            }
            // 若没有转换则抛出异常
            throw new System.Exception("不支持的数据库数据类型:" + ValueType.FullName);
        }

        #endregion

    }
}